package dados;
import java.io.Serializable;
import java.util.List;

import sistema.Agenda;
import sistema.Email;




/**
 * Classe Usuario, que possui um login (email), senha, perfil, eventos futuros,eventos passados, contatos e etc.
 */

public class Usuario implements Serializable {
	private static final long serialVersionUID = 1L;
	private String email, senha;
	private Perfil perfil;
	private Agenda agenda;
	
	/**
	 * Constroi um Usuario a partir de um email uma senha e um objeto Perfil.
	 * @param email O e-mail do Usuario, que tambem eh o seu login.
	 * @param senha A senha do Usuario
	 * @param perfil o Perfil do usuario.
	 */
	public Usuario(String email, String senha, Perfil perfil){
		this.email = email;
		this.senha = senha;
		this.perfil = perfil;
		agenda = new Agenda();
	}
	/**
	 * Retorn o e-mail do usuario
	 * @return
	 */
	public String getEmail(){
		return email;
	}
	/**
	 * Retorna o perfil do usuario
	 * @return
	 */
	public Perfil getPerfil(){
		return perfil;
	}
	/**
	 * Modifica a senha do Usuario.
	 * @param Senha a nova senha.
	 */
	public void setSenha(String senha){
		this.senha = senha;
	}

	/**
	 * Retorna a lista de contatos do usuario.
	 * @return
	 */
	public List<Contato> getContatos(){
		return agenda.getContatos();
	}
	/**
	 * Retorna a ista de eventos futuros
	 * @return
	 */
	public List<Evento> getEventosFuturos(){
		agenda.reorganizaEventos();
		return agenda.getEventosFuturos();
	}
	/**
	 * retorna a lista de eventos passados
	 * @return
	 */
	public List<Evento> getEventosPassados(){
		agenda.reorganizaEventos();
		return agenda.getEventosPassados();
	}
	/**
	 * Addiciona um novo evento a agenda do usuario.
	 * @param evento O evento a ser Adicionado.
	 * @param sobrecarregar Se deve fazer sobrecarga de horario ou nao.
	 * @return Um objeto Evento se houve conflito de horario,null se o novo evento foi corretamente adicionado.
	 */

	public Evento addEvento(Evento evento,boolean sobrecarregar){
		return agenda.addEvento(evento, sobrecarregar);
	}
	/**
	 * Adiciona um evento sobrescrevendo todos os que derem conflito de horario com ele.
	 * @param evento O evento a ser adicionado
	 */

	public void sobrescreveEventosConflitantes(Evento evento){
		agenda.sobrescreveEventosConflitantes(evento);
	}
	/**
	 * Procura por um contato cujo nome comeca com a string dada
	 * @param nome Parte do nome, ou nome completo do contato
	 * @return Uma lista de contatos desejado
	 */
	public List<Contato> procuraContato(String nome){
		return agenda.procuraContato(nome);
	}
	/**
	 * Procura por eventos associados a um certo contato.
	 * @param c1 o Contato desejado.
	 * @return Uma Lista de Eventos associados a c1.
	 */
	public List<Evento> procuraEventoPorContato(Contato c1){
		return agenda.procuraEventoPorContato(c1);
	}
	/**
	 * Remove um contato da lista de contatos
	 * @param contato Contato a ser removido
	 */
	public void removeContato(Contato contato){
		agenda.removeContato(contato);
	}

	/**
	 * Adiciona um novo contato a Agenda do Usuario, se for achado um com mesmo e-mail,
	 * o metodo olha se deve ser sobrescrito o contato antigo, caso nao, o contato nao sera adicionado.
	 * @param contato O contato a ser adicionado.
	 * @param sobrescrever Se o Usuario deseja Sobrescrever o Contato antigo ou nao.
	 * @return
	 */
	public boolean addContato(Contato contato,boolean sobrescrever){
		return agenda.addContato(contato, sobrescrever);
	}

	/**
	 * Compara se o argumento passado eh a senha do usuario.
	 * @param senha A senha a ser comparada.
	 * @return A igualdade ou nao.
	 */
	public boolean comparaSenha(String senha){
		return this.senha.equals(senha);
	}
	/**
	 * Uma String representando a lista de eventos do Usuario
	 * @return
	 */
	public String listaEventos(){
		return agenda.listaEventos();
	}

	/**
	 * Retorna uma lista com os eventos cujo nome contem os caracteres passados como parametro
	 * @param nome Nome para pesquisar pelo evento
	 * @return Uma lista com os eventos cujo nome tem uma intersecao com o nome passado
	 */
	public List<Evento> procuraEvento(String nome){
		return agenda.procuraEvento(nome);
	}
	/**
	 * Remove um evento da lista de eventos em que ele estiver presente. 
	 * 
	 * @param evento O objeto evento a ser removida
	 */
	//pensei em, na interface, verfica com o metodo procuraEvento, e manda remover com esse.
	public void removeEvento(Evento evento){
		agenda.removeEvento(evento);
	}
	private String getSenha(){
		//Para recuperar senha
		return senha;
	}
	/**
	 * Recupera a senha do usuario e envia para o e-mail.
	 * @param l1 a lista de usuarios
	 * @param email o email do usuario que esqueceu a senha	
	 * @return true se nao houve erro
	 * @throws Exception
	 */
	public static boolean recuperaSenha(List<Usuario> l1, String email) throws Exception{
		for (Usuario usuario : l1) {
			if (usuario.getEmail().equals(email)){
				Email.sendMail("Senha do Diario", "Login: " + email + "\nSenha: " + usuario.getSenha(), email);
				return true;
			}
		}
		throw new Exception("Usuario nao encontrado.");
	}

	/**
	 * Retorna a lista de Contatos associados ao evento.
	 * @param evento Evento a ser chegado.
	 * @return um List<Candidato>.
	 */
	public List<Contato> contatosDoEvento(Evento evento){
		return agenda.contatosDoEvento(evento);
	}
	/**
	 * Uma representacao em String do Usuario
	 */
	@Override
	public String toString() {
		return getPerfil().toString()+"\n Contatos: "+getContatos()+"\n Eventos: "+getEventosFuturos();
	}
	/**
	 * Compara igualdade entre Usarios, que sao iguais se seus Perfils forem iguais.
	 */
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Usuario)){
			return false;
		}
		Usuario outro = (Usuario) obj;
		return getPerfil().equals(outro.getPerfil());
	}
}
